package com.simtop.utils.excel;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

/**
 * @ClassName ExcelUtils
 * @Description TODO  导入导出工具类
 * @Author lvyongwei
 * @Date 2020-05-21 14:09
 **/
@Component
public class ExcelUtils {

    /**
     * @param is   导入文件输入流
     * @param clazz Excel实体映射类
     * @return
     */
    public static List<BaseRowModel> readExcel(InputStream is, Class clazz){
        BufferedInputStream bis = null;
        List<BaseRowModel> lists=null;
        try {
            bis = new BufferedInputStream(is);
            // 解析每行结果在listener中处理
            ExcelListener listener = new ExcelListener();
            ExcelReader excelReader = EasyExcelFactory.getReader(bis, listener);
            excelReader.read(new Sheet(1, 1, clazz));
            System.err.println(123);
            lists=listener.getDatas();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return lists;
    }

    /**
     * @param os 文件输出流
     * @param clazz Excel实体映射类
     * @param data 导出数据
     * @return
     */
    public static Boolean writeExcel(OutputStream os, Class clazz, List<? extends BaseRowModel> data){
        BufferedOutputStream bos= null;
        try {
            bos = new BufferedOutputStream(os);
            ExcelWriter writer = new ExcelWriter(bos, ExcelTypeEnum.XLSX);
            //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
            Sheet sheet1 = new Sheet(1, 0,clazz);
            writer.write(data, sheet1);
            writer.finish();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * 下载模板
     * @param request
     * @param response
     * @param clazz   要下载的实体类对象
     * @param fileName  要导出的模板文件名字
     */
    public void cooperation(HttpServletRequest request, HttpServletResponse response,Class clazz,String fileName) {
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            //String fileName = "导入模板";
            response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")+".xlsx");
            ExcelUtils.writeExcel(out, clazz ,null);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 导入对象
     * @param file
     * @param clazz   导入对象的字节码文件
     * @return    返回值为对象集合   可进行插入操作
     */
    public List<BaseRowModel> upload(@RequestParam("file") MultipartFile file,Class clazz) {
        List<BaseRowModel> list=null;
        try {
            if (file.isEmpty()) {
                return list;
            }else{
                // 获取文件名
                String fileName = file.getOriginalFilename();
                // 获取文件的后缀名
                String suffixName = fileName.substring(fileName.lastIndexOf("."));
                //创建一个临时文件，用于暂时存放
                File tmpFile = File.createTempFile("tmp", null);
                //将MultipartFile 转换为 File 临时文件
                file.transferTo(tmpFile);
                //将临时文件转为输入流
                InputStream inputStream = new FileInputStream(tmpFile);
                list=ExcelUtils.readExcel(inputStream, clazz);
                //上传完成 删除临时文件
                tmpFile.delete();
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 导出内容
     * @param request
     * @param response
     * @param data   要导出的数据集合
     * @param fileName   导出excel表名字
     * @param clazz      导出实体的字节码文件
     */
    public void cooperationData(HttpServletRequest request, HttpServletResponse response,List<? extends BaseRowModel> data,String fileName,Class clazz) {
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");

            response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")+".xlsx");
            //把数据明细放在list data中
            //System.out.println("把数据明细放在list data中:请完善查询数据接口调用，并把查询结果写入list data中");
            Boolean flag = ExcelUtils.writeExcel(out, clazz, data);
            //System.out.println("导出是否成功："+flag);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}